Link to this headingPBKDF1
- Do not Use
- Using HMAC Key Derivation Functions (HKDF) is less secure than using [PBKDF2](/Crypto/Key Derivation/PBKDF2), [Bcrypt](/Crypto/Hash Functions/BCrypt), [Scrypt](/Crypto/Key Derivation/Scrypt) or [Argon2](/Crypto/Key Derivation/Argon2).
Since the Input to the function is of fixed size and exactly equal to the output size there is a smaller amount of possible inputs and also it makes the 2 iteration have the same possible inputs as the 10th iteration.
Either there will be a larger possibility for collision of two arbitrary messages.
Or there will be a cycle where hashing a message creates the same output as hashing the same message N times.
Link to this headingSecurity
Link to this headingCycle Detection Attacks
Because the default version of this just takes the output hash and uses it as the full message for the next cycle there is a reduction in the randomness and can possobly converge. This is improbable for strong hash algoruthums but is possoble for weaker ones.
PoC for a non-secure Hashfunction:
"""Truncated CRC32 -> 16-bit big-endian two-byte digest."""
= & 0xFFFFFFFF
return
=
=
return
=
=
= 0
=
=
+= 1
return False, None, None, None,
# find mu
= 0
=
=
=
+= 1
# find lambda
= 1
=
=
+= 1
return True, , , ,
# Use the concrete bytes found earlier
= b # bytes: 26 8d 3d 03 c1
= # b'&\x8d'
= # b'=\x03\xc1'
# Compute T0
=
# Show a short sequence of iterates
=
=
# Floyd cycle detection starting at T0
, , , , =
# Show derived digest for several iteration counts
=
# Also demonstrate that applying H to the 2-byte state yields same value (fixed point)
=
"""
Using combined bytes (password||salt): 268d3d03c1 -> password: 268d salt: 3d03c1
T0 = H(password||salt) = 9479
Sequence of iterates (first 8):
0: 9479
1: 9479
2: 9479
3: 9479
4: 9479
5: 9479
6: 9479
7: 9479
Floyd cycle detection result:
found: True mu: 0 lambda: 1 meeting_state: 9479 steps_taken: 0
Derived digest after 1 iterations: 9479
Derived digest after 2 iterations: 9479
Derived digest after 3 iterations: 9479
"""
Link to this headingImplementation
How it works:
assert
return
return
return
#Get hash_function block_size
=
# Check if key is longer than block size.
# IF it is then hash the key. This makes the keysize the same as the output of the hashfunction
=
# IF key is shorter
# Pad the key to blocksize
= + b *
#print(key, len(key), block_size)
# Create Keys
=
=
#Hash i_key and message
=
#Hash the o_key and the hashed output of above
return
=
#Check if keylength is too big for hash function
#Do Loop for iterations
=
#Return the hash with the correct size
return
#47e97e39e2b32b15eb9278e53f7bfca57f8e6b2c